package cn.shoukaiseki.sjf4j;

import cn.shoukaiseki.sjf4j.fastjson.Fastjson2Impl;
import cn.shoukaiseki.sjf4j.jackson.JacksonImpl;

/**
 * 直接调用是线程安全的
 * <br>
 * cn.shoukaiseki.sjf4j.Sjf4jFactory
 * <br>
 * @author shoukaiseki
 * 主页 https://gitee.com/shoukaiseki/<br>
 * E-mail jiang28555@qq.com<br>
 * @date 2024-05-23 01:23:51<br>
 */
public class Sjf4jFactory {

    /**
     * fastjson2包中包含的类名
     */
    public static final String FASTJSON2_CONTAIN_CLASS_NAME ="com.alibaba.fastjson2.JSONFactory";

    public static final String JACKSON_CONTAIN_CLASS_NAME="com.fasterxml.jackson.databind.ObjectMapper";


    private static Sjf4j sjf4j;

    private static JsonParserType jsonParserType;

    /**
     * 设置默认解析器,
     */
    private static boolean firstSetup=false;

    static {
        JsonParserType type=null;
        try{
            if (ClassLoader.getSystemClassLoader().loadClass(FASTJSON2_CONTAIN_CLASS_NAME) != null) {
                type = JsonParserType.FASTJSON2;
            }
        }catch (Throwable t){}
        try{
            if(sjf4j ==null) {
                if (ClassLoader.getSystemClassLoader().loadClass(JACKSON_CONTAIN_CLASS_NAME)!=null) {
                    type = JsonParserType.JACKSON;
                }
            }
        }catch (Throwable t){}

        if(type==null){
            throw new RuntimeException("没有可用的json解析库,请引入fastjson2或者jackson的jar包");
        }
        sjf4j=getSjf4jByType(type);
        jsonParserType=type;
    }



    /**
     * 设置默认的json解析器
     * <p>
     * 在同时引入了fastjson2和jackson的json解析jar包时,优先采用fastjson2,
     * <p>
     *  如果要强制设置jackson做为默认解析器,则使用  * <code>Sjf4jFactory.setDefaultSjf4j(new JacksonImpl());</code> 设置
     * @param type  {@link JsonParserType}
     */
    public static void setDefaultSjf4j(JsonParserType type){
        Sjf4jFactory.sjf4j=getSjf4jByType(type);
        Sjf4jFactory.jsonParserType =type;
    }


    /**
     * 根据类型获取sjf4j,不推荐使用该方法
     * <p>
     *  只有在一些特殊情况下才使用,比如{@link #setDefaultSjf4j(JsonParserType)}之前执行了{@link #getSjf4j()} 或者 {@link #getSingleSjf4j()},会使之前获取的
     * @param type
     * @return
     */
    public static Sjf4j getSjf4jByType(JsonParserType type){
        if(type==null){
            throw new RuntimeException("解析器类型不能为空");
        }
        Sjf4j sjf4j=null;
        if(type== JsonParserType.JACKSON){
            sjf4j =new JacksonImpl();
        }else if(type== JsonParserType.FASTJSON2){
            sjf4j = new Fastjson2Impl();
        }else{
            throw new RuntimeException("不支持的解析器类型");
        }
        return sjf4j;
    }

    /**
     * 获取单例的sjf4j,单例的也是线程安全的
     */
    public static Sjf4j getSingleSjf4j(){
        return sjf4j;
    }

    /**
     * 创建一个新的sjf4j
     */
    public static Sjf4j getSjf4j(){
        return getSjf4jByType(Sjf4jFactory.jsonParserType);
    }

    /**
     * 该方法用于Test
     * @return
     */
    protected static Sjf4j getFastJsonSjf4j(){
        return new Fastjson2Impl();
    }

    /**
     * 用于测试
     * @return
     */
    protected static Sjf4j getJacksonSjf4j(){
        return new JacksonImpl();
    }

//    public static String toJsonString(Object obj){
//     return sjf4j.toJsonString(obj);
//    }




    /**
     * 支持的json解析器类型
     */
    public enum JsonParserType {
        FASTJSON2,JACKSON;;
    }
}
